<template>
  <div class="table-index-wrapper" :class="{ srcrollbar_fixed: srcrollbar_fixed }">
    <table-header ref="tableHeaderRef" :show-filter="false" v-if="(table.buttons && table.buttons.length > 0) || $slots['table-summary']">
      <template #table-header-before>
        <slot name="table-header-before"></slot>
      </template>
      <template #table-header-after>
        <slot name="table-header-after"></slot>
      </template>
      <template #table-summary>
        <slot name="table-summary"></slot>
      </template>
      <template #table-config>
        <a-space size="medium">
          <template v-for="(item, index) in table.buttons" :key="index">
            <span v-if="itemButtonIsShow(item)">
              <slot v-if="item.type === 'slot'" :name="item.slotName"></slot>
              <a-button v-else :type="item.type" @click="handleButtonEvent(item)">
                <template #icon v-if="item.icon">
                  <component :is="`icon-${item.icon}`" />
                </template>
                {{ item.label }}
              </a-button>
            </span>
          </template>
        </a-space>
      </template>
    </table-header>
    <a-table
      v-bind="table"
      :bordered="table.bordered || { cell: true }"
      :stripe="table.striped"
      :loading="table.tableLoading"
      :data="table.dataList"
      :pagination="false"
      :columns="table.columns"
      :scroll="
        table.scroll || {
          minWidth: tableMinWidth,
          y: table.tableHeight ? table.tableHeight : 300,
        }
      "
      :row-selection="table.rowSelection"
      :selectedKeys="selectedKeys"
      :row-key="rowKey"
      :expanded-keys="expandedKeys"
      table-layout-fixed
      @select="select"
      @select-all="selectAll"
      @selection-change="selectionChange"
      @expand="expand"
      @sorterChange="sorterChangeFn"
      :row-class="rowClass"
    >
      <template #columns>
        <a-table-column v-for="item of table.columns" :key="item.dataIndex" v-bind="item">
          <template v-if="item.titleSlotName || item.titleTooltipContent" #title>
            <!-- titleSlotName 插槽 -->
            <slot v-if="item.titleSlotName" :name="item.titleSlotName" :column="item"></slot>
            <!-- 标题后增加 titleTooltip 组件 -->
            <title-tooltip v-if="item.titleTooltipContent" v-bind="{ title: item.title, titleTooltipContent: item.titleTooltipContent }" />
          </template>
          <template v-if="item.slotName || item.render || item.ellipsis" #cell="{ record, column, rowIndex }">
            <!-- 优先 slot -->
            <template v-if="item.slotName">
              <slot :name="item.slotName" v-bind="{ record, column, rowIndex }"></slot>
            </template>
            <!-- ellipsis -->
            <template v-else-if="item.ellipsis">
              <a-typography-paragraph
                style="margin-bottom: 0"
                :key="record[column.dataIndex]"
                :ellipsis="{
                  rows: 3,
                  showTooltip: true,
                }"
              >
                <!-- ellipsis 兼容 render -->
                <template v-if="item.render">
                  <compnoent v-if="isVNode(item.render(record, column))" :is="item.render(record, column)" />
                  <template v-else>
                    {{ item.render(record, column) }}
                  </template>
                </template>
                <template v-else>
                  {{ record[column.dataIndex] || '-' }}
                </template>
              </a-typography-paragraph>
            </template>
            <!-- render -->
            <template v-else>
              <component v-if="isVNode(item.render(record, column))" :is="item.render(record, column)" />
              <template v-else>
                {{ item.render(record, column) || '-' }}
              </template>
            </template>
          </template>
        </a-table-column>
        <a-table-column
          v-if="table.operates"
          key="operate"
          data-index="operate"
          align="left"
          title="操作"
          :width="operateWidth"
          fixed="right"
        >
          <template #cell="{ record, column, rowIndex }">
            <operate-list :key="record[rowKey]" :operates="table.operates" :cell="{ record, column, rowIndex }" />
          </template>
        </a-table-column>
      </template>
      <template #expand-icon="{ expanded, record }">
        <slot name="expand-icon" :expanded="expanded" :record="record"></slot>
      </template>
      <template #expand-row="{ record }" v-if="$slots['expand-row']">
        <slot name="expand-row" :record="record"></slot>
      </template>
      <template #empty v-if="$slots.empty">
        <slot name="empty"></slot>
      </template>
    </a-table>
    <table-footer
      v-if="table.pagination"
      ref="tableFooterRef"
      :pagination="table.pagination"
      :showRefresh="false"
      position="end"
      @change="pagenationChangeFn"
    />
  </div>
</template>

<script setup>
  import { useTableHeight } from '@/hooks/table'
  import { useDebounceFn } from '@vueuse/core'
  import { getCurrentInstance, computed, onMounted, onBeforeUnmount, inject, isReactive, isVNode, reactive, ref } from 'vue'
  // tableQueryParam
  const tableQueryParam = inject('table-queryParam')
  // 定义 props
  const props = defineProps({
    table: {
      type: Object,
      default: () => {},
    },
    rowKey: {
      type: String,
      default: 'id',
    },
    rowSelection: {
      type: Boolean,
      default: false,
    },
    expandedKeys: {
      type: Array,
    },
    selectedKeys: {
      type: Array,
    },
    rowClass: {
      type: Function,
    },
    // 最后一列操作列的列表
    operateColumnWidth: Number,
  })
  // 定义 emit
  const emit = defineEmits(['sortChange', 'loadData', 'select', 'selectAll', 'selectionChange', 'pagenationChange', 'expand'])
  const handleButtonEvent = function (item) {
    item.method()
  }
  const sorterChangeFn = function (prop, direction) {
    if (tableQueryParam) {
      const columns = props.table.columns
      const columnConfig = columns.find((item) => item.dataIndex == prop)
      // 字段的排序配置
      const sortable = columnConfig.sortable
      if (sortable) {
        // 默认为 api 接口排序，如传入了 false，则走默认前端排序
        const sortByApi = sortable.sortByApi
        if (sortByApi != false) {
          if (isReactive(tableQueryParam)) {
            // 排序字段
            tableQueryParam.sortField = prop
            // 排序方向
            if (direction == 'ascend') {
              tableQueryParam.sortType = 'asc'
            } else if (direction == 'descend') {
              tableQueryParam.sortType = 'desc'
            } else {
              tableQueryParam.sortType = ''
            }
          } else {
            // 排序字段
            tableQueryParam.value.sortField = prop
            // 排序方向
            if (direction == 'ascend') {
              tableQueryParam.value.sortType = 'asc'
            } else if (direction == 'descend') {
              tableQueryParam.value.sortType = 'desc'
            } else {
              tableQueryParam.value.sortType = ''
            }
          }
          emit('loadData')
        }
      }
    }
  }
  const pagenationChangeFn = () => {
    emit('loadData')
    emit('pagenationChange')
  }
  const select = (rowKeys, rowKey, record) => {
    emit('select', rowKeys, rowKey, record)
  }
  const selectAll = (selectedRowKeys) => {
    emit('selectAll', selectedRowKeys)
  }
  const selectionChange = (selectedRowKeys) => {
    emit('selectionChange', selectedRowKeys)
  }
  const expand = (expandedKeys) => {
    emit('expand', expandedKeys)
  }
  // 控制按钮是否显示
  const itemButtonIsShow = (btn) => {
    return btn.show !== false && (typeof btn.show === 'function' ? btn.show() : true) && (btn.permission ? btn.permission.flag : true)
  }
  // 最后一列操作列的宽度
  const operateWidth = computed(() => {
    let operates = props.table.operates
    let operateColumnWidth = props.table.operateColumnWidth
    if (operateColumnWidth) {
      return operateColumnWidth
    }
    if (operates?.length > 0) {
      if (operates.length >= 2) {
        return 170
      } else {
        if (operates[0]?.width) {
          return operates[0].width
        } else {
          return 85
        }
      }
    }
    return 0
  })
  const tableMinWidth = computed(() => {
    const { columns, operates } = props.table
    let minWidth = 0
    if (operates) {
      minWidth += operateWidth.value
    }
    columns.forEach((column) => {
      minWidth += Number(column.width) || Number(column.minWidth) || 130
    })
    return minWidth
  })
  const instance = getCurrentInstance()
  const calcTableHeightFn = useDebounceFn(async () => {
    const height = await useTableHeight(instance)
    const table = props.table
    table.tableHeight = height
  }, 200)

  const srcrollbar_fixed = ref(false)
  onMounted(() => {
    if (!props.table.tableHeight) {
      // 获取 tableHeight
      calcTableHeightFn()
      window.addEventListener('resize', calcTableHeightFn)
    }
    const parentNode = instance.vnode.el.parentNode
    if (parentNode?.className == 'page-container') {
      srcrollbar_fixed.value = true
    }
  })
  onBeforeUnmount(() => {
    if (!props.table.tableHeight) {
      window.removeEventListener('resize', calcTableHeightFn)
    }
  })

  defineExpose({
    calcTableHeightFn,
  })
</script>
<style lang="less" scoped>
  :deep(.arco-table-td-content:empty::before) {
    content: '-';
  }

  :deep(.td-divider) {
    position: relative;
    height: 18px;
    &::before {
      content: '';
      display: block;
      position: absolute;
      left: -12px;
      right: -12px;
      top: 9px;
      height: 0.5px;
      background-color: #e5e6eb;
    }
  }

  .srcrollbar_fixed {
    :deep(.arco-scrollbar-track-direction-horizontal) {
      bottom: 22px;
      position: fixed;
      margin-left: 260px;
    }
  }
  .main-layout-close-status .srcrollbar_fixed {
    :deep(.arco-scrollbar-track-direction-horizontal) {
      margin-left: 120px;
    }
  }
</style>
